package club.zhcs.service.auth;

import static club.zhcs.vo.Application.PAGESIZE;

import java.util.Collections;
import java.util.List;

import org.nutz.dao.Cnd;
import org.nutz.dao.Condition;
import org.nutz.dao.Dao;
import org.nutz.dao.entity.Record;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.ContinueLoop;
import org.nutz.lang.Each;
import org.nutz.lang.ExitLoop;
import org.nutz.lang.Lang;
import org.nutz.lang.LoopException;

import com.kerbores.utils.collection.Lists;
import com.kerbores.utils.db.SqlActuator;
import com.kerbores.utils.entries.Result;
import com.kerbores.utils.web.pager.Pager;

import club.zhcs.bean.auth.Role;
import club.zhcs.bean.auth.RolePermission;
import club.zhcs.bean.auth.User.Type;
import club.zhcs.dao.acl.RoleDao;
import club.zhcs.dao.acl.RolePermissionDao;

/**
 * 
 * @author 王贵源
 *
 * @email kerbores@kerbores.com
 *
 * @description 角色业务
 * 
 * @copyright 内部代码,禁止转发
 *
 *
 * @time 2016年1月26日 下午2:45:28
 */
@IocBean
public class RoleService {
	@Inject
	RoleDao roleDao;

	@Inject
	private RolePermissionDao rolePermissionDao;

	@Inject
	private RolePermissionService rolePermissionService;

	/**
	 * 根据用户查询
	 * 
	 * @param id
	 *            用户 id
	 * @param type
	 *            用户类型
	 * @return 角色列表
	 *
	 * @author 王贵源
	 */
	public List<Role> findByUserId(int id, Type type) {
		final Dao dao = roleDao.getDao();// 获取数据访问对象

		final List<Role> roles = Lists.newArrayList();
		// 获取配置的sql
		Sql sql = dao.sqls().create("find.role.by.user.id");

		sql.params().set("userid", id);// 注入sql参数
		sql.params().set("type", type);

		List<Record> records = SqlActuator.runReport(sql, dao);// 执行sql

		Lang.each(records, new Each<Record>()// 将记录转换成对象
		{

			@Override
			public void invoke(int index, Record record, int length) throws ExitLoop, ContinueLoop, LoopException {
				roles.add(record.toEntity(dao.getEntity(Role.class)));
			}
		});

		return roles;
	}

	/**
	 * 根据名称查询
	 * 
	 * @param name
	 *            角色名称
	 * @return 角色
	 *
	 * @author 王贵源
	 */
	public Role findByName(String name) {
		return roleDao.findByCondition(Cnd.where("name", "=", name));
	}

	/**
	 * 添加角色
	 * 
	 * @param role
	 *            待添加角色
	 * @return 角色 将携带数据库 id
	 *
	 * @author 王贵源
	 */
	public Role addRole(Role role) {
		return roleDao.save(role);
	}

	/**
	 * 根据 id 查询
	 * 
	 * @param id
	 *            角色 id
	 * @return 角色
	 *
	 * @author 王贵源
	 */
	public Role findById(int id) {
		return roleDao.findById(id);
	}

	/**
	 * 更新角色
	 * 
	 * @param role
	 *            待更新角色
	 * @param updateField
	 *            待更新字段
	 * @return 更新结果
	 *
	 * @author 王贵源
	 */
	public Result upate(Role role, String... updateField) {
		return roleDao.update(role, updateField) ? Result.success() : Result.fail("更新角色信息失败");
	}

	/**
	 * 删除角色
	 * 
	 * @param id
	 *            角色 id
	 * @return 删除结果
	 *
	 * @author 王贵源
	 */
	public Result delete(int id) {
		return roleDao.delById(id) ? Result.success() : Result.fail("删除角色失败");
	}

	/**
	 * 查询全部
	 * 
	 * @return 全部角色
	 *
	 * @author 王贵源
	 */
	public List<Role> findAll() {
		return roleDao.findAll();
	}

	/**
	 * 分页查询
	 * 
	 * @param page
	 *            页码
	 * @return 角色分页对象
	 *
	 * @author 王贵源
	 */
	public Pager<Role> findByPage(int page) {
		Pager<Role> pager = new Pager<Role>(PAGESIZE, page);
		pager.setEntities(roleDao.searchByPage(null, page, PAGESIZE));
		pager.setCount(roleDao.countAll());
		return pager;

	}

	/**
	 * 关键词查询
	 * 
	 * @param page
	 *            页码
	 * @param key
	 *            关键词
	 * @return 角色分页对象
	 *
	 * @author 王贵源
	 */
	public Pager<Role> searchByKey(int page, String key) {
		String searchKey = String.format("%%%s%%", key);
		Condition cnd = Cnd.where("name", "like", searchKey).or("description", "like", searchKey);
		Pager<Role> pager = new Pager<Role>(PAGESIZE, page);
		pager.setEntities(roleDao.searchByPage(cnd, page, PAGESIZE));
		pager.setCount(roleDao.countByCnd(cnd));
		return pager;
	}

	/**
	 * 设置权限
	 * 
	 * @param ids
	 *            权限 id 串
	 * @param roleId
	 *            角色 id
	 * @return 处理结果
	 *
	 * @author 王贵源
	 */
	public Result setPermission(int[] ids, int roleId) {
		/**
		 * 1.查询全部权限列表<br>
		 * 2.遍历权限.如果存在,则更新时间.如果不存在则删除,处理之后从目标数组中移除;<br>
		 * 3.遍历余下的目标数组
		 */
		if (ids == null) {
			ids = new int[] {};
		}
		List<Integer> newIds = Lang.array2list(ids, Integer.class);
		Collections.sort(newIds);
		List<RolePermission> rolePermissions = rolePermissionDao.search(Cnd.where("roleId", "=", roleId));
		for (RolePermission role : rolePermissions) {
			int i = 0;
			if ((i = Collections.binarySearch(newIds, role.getPermissionId())) >= 0) {
				newIds.remove(i);
				// role.setCreateTime(now());
				rolePermissionDao.update(role);
			} else {
				rolePermissionDao.delById(role.getId());
			}
		}
		for (int pid : newIds) {
			RolePermission rolep = new RolePermission();
			rolep.setRoleId(roleId);
			rolep.setPermissionId(pid);
			rolePermissionDao.save(rolep);
		}
		return Result.success();
	}

	/**
	 * 根据角色 id 查询权限及其授权情况
	 * 
	 * @param id
	 *            角色 id
	 * @return 记录列表
	 *
	 * @author 王贵源
	 */
	public List<Record> findPermissionsWithRolePowerdInfoByRoleId(int id) {
		Dao dao = roleDao.getDao();
		Sql sql = dao.sqls().create("find.permissions.with.role.powered.info.by.role.id");
		sql.params().set("id", id);
		return SqlActuator.runReport(sql, dao);
	}

}
